package com.myimooc.shiro.web.session;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;

import javax.servlet.ServletRequest;
import java.io.Serializable;

/**
 * @className: CustomSessionManager
 * @description: 自定义SessionManager，实现先访问request对象，再访问Redis，最后访问数据库
 * @date: 2020/5/12
 * @author: cakin
 */
public class CustomSessionManager extends DefaultWebSessionManager {

    /**
     * 功能描述：自定义SessionManager
     *
     * @author cakin
     * @date 2020/5/13
     * @param sessionKey session键
     * @return Session session
     */
    @Override
    protected Session retrieveSession( SessionKey sessionKey ) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
        ServletRequest request = null;
        if (sessionKey instanceof WebSessionKey) {
            request = ((WebSessionKey) sessionKey).getServletRequest();
        }
        // 访问request对象，从中获得session
        if (request != null && sessionId != null) {
            Session session = (Session) request.getAttribute(sessionId.toString());
            if (session != null) {
                return session;
            }
        }
        // 从redis获取session
        Session session = super.retrieveSession(sessionKey);
        if (request != null && sessionId != null) {
            // 把session放到request对象，下次就可以从request中获取session，可以减少对Redis的访问压力
            request.setAttribute(sessionId.toString(), session);
        }
        return session;
    }
}
